<template>
  <div>
    <a-form-model :label-col="labelCol" :wrapper-col="wrapperCol">
      <a-collapse v-model="activeKey">
        <a-collapse-panel key="1" header="查询">
          <div style="justify-content: flex-start; display: flex">
            <div style="width: 500px">
              <div style="justify-content: flex-start; display: flex">
                <div style="text-align: right; min-width: 150px; padding: 0 20px">执行对象</div>
                <a-select
                  v-model="queryBean"
                  :show-search="true"
                  :not-found-content="null"
                  :filter-option="true"
                  :allowClear="true"
                  placeholder="请选择或输入"
                  @search="handleSearch"
                  @change="changeQueryOptions"
                >
                  <a-select-option
                    v-for="(item, index) in showCommonQueryOptions"
                    :key="'queryOptions' + index"
                    :value="item"
                  >
                    {{ item }}
                    <a-icon
                      style="position: absolute; top: 30%; right: 10%"
                      type="delete"
                      @click.stop="deleteItem(item)"
                    />
                  </a-select-option>
                </a-select>
              </div>
            </div>
            <div style="width: 300px">
              <div style="justify-content: flex-start; display: flex">
                <div style="text-align: right; min-width: 150px; padding: 0 20px">查询表</div>
                <a-input v-model="queryTableName" />
              </div>
            </div>
          </div>
          <div style="justify-content: flex-start; display: flex">
            <div style="text-align: right; min-width: 150px; padding: 0 20px">查询条件</div>
            <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
              <div
                style="display: flex; justify-content: flex-start; margin-right: 30px"
                v-for="(param, index) in queryParams"
                :key="'queryParams_' + index"
              >
                <div style="width: 220px">
                  <a-input style="width: 200px" v-model="queryParams[index].key" />
                </div>
                <div style="width: 160px">
                  <a-select style="width: 150px" v-model="queryParams[index].operator">
                    <template v-for="(item, oindex) in operator">
                      <a-select-option :key="'queryoperator' + oindex" :value="item.name">
                        {{ item.name }}
                      </a-select-option>
                    </template>
                  </a-select>
                </div>
                <div style="width: 220px">
                  <a-input style="width: 200px" :key="'queryValue' + index" v-model="queryParams[index].value" />
                </div>
                <div style="width: 220px" v-if="queryParams[index].operator == 'Between'">
                  <a-input
                    style="width: 200px"
                    :key="'queryValue' + index + '_1'"
                    v-model="queryParams[index].value1"
                  />
                </div>
                <div style="width: 20px">
                  <div style="line-height: 32px; margin-left: 5px">
                    <a-icon v-if="index > 0" type="minus-circle" @click="removeQueryParams(index)" />
                    <a-icon v-if="index == 0" type="plus-circle" @click="addQueryParams" />
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div
            style="
              margin-left: 30px;
              justify-content: flex-end;
              display: flex;
              align-items: center;
              height: 60px;
              padding-right: 50px;
            "
          >
            <a-button type="primary" @click="handlerSearch">查询</a-button>
          </div>
          <a-table
            :columns="columns"
            :data-source="records"
            :pagination="false"
            bordered
            :scroll="{ x: 1800 }"
            :rowKey="(record) => record.randomStr"
            :customRow="customRow"
          >
          </a-table>
          <a-pagination
            show-size-changer
            :default-current="1"
            :total="pagination.total"
            @change="pageChange"
            @showSizeChange="onShowSizeChange"
            :show-total="(total) => `共 ${total} 条记录`"
          />
        </a-collapse-panel>
        <a-collapse-panel key="2" header="更新" :disabled="false">
          <div style="justify-content: flex-start; display: flex">
            <div style="width: 500px">
              <div style="justify-content: flex-start; display: flex">
                <div style="text-align: right; min-width: 150px; padding: 0 20px">执行对象</div>
                <a-select
                  v-model="updateBean"
                  :show-search="true"
                  :not-found-content="null"
                  :filter-option="true"
                  :allowClear="true"
                  placeholder="请选择或输入"
                  @search="handleSearch"
                  @change="changeUpdateOptions"
                >
                  <a-select-option
                    v-for="(item, index) in showCommonQueryOptions"
                    :key="'queryOptions' + index"
                    :value="item"
                  >
                    {{ item }}
                    <a-icon
                      style="position: absolute; top: 30%; right: 10%"
                      type="delete"
                      @click.stop="deleteItem(item)"
                    />
                  </a-select-option>
                </a-select>
              </div>
            </div>
            <div style="width: 300px">
              <div style="justify-content: flex-start; display: flex">
                <div style="text-align: right; min-width: 150px; padding: 0 20px">查询表</div>
                <a-input v-model="updateTableName" />
              </div>
            </div>
            <div style="width: 300px">
              <div style="justify-content: flex-start; display: flex">
                <div style="text-align: right; min-width: 150px; padding: 0 20px">最大执行数量</div>
                <a-input v-model="maxSize" type="number" />
              </div>
            </div>
          </div>
          <div style="justify-content: flex-start; display: flex">
            <div style="text-align: right; min-width: 150px; padding: 0 20px">更新条件</div>
            <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
              <div
                style="display: flex; justify-content: flex-start; margin-right: 30px"
                v-for="(param, index) in updateParams"
                :key="'updateParams_' + index"
              >
                <div style="width: 220px">
                  <a-input style="width: 200px" v-model="updateParams[index].key" />
                </div>
                <div style="width: 160px">
                  <a-select style="width: 150px" v-model="updateParams[index].operator">
                    <template v-for="(item, oindex) in operator">
                      <a-select-option :key="'queryoperator' + oindex" :value="item.name">
                        {{ item.name }}
                      </a-select-option>
                    </template>
                  </a-select>
                </div>
                <div style="width: 220px">
                  <a-input style="width: 200px" :key="'queryValue' + index" v-model="updateParams[index].value" />
                </div>
                <div style="width: 220px" v-if="updateParams[index].operator == 'Between'">
                  <a-input
                    style="width: 200px"
                    :key="'queryValue' + index + '_1'"
                    v-model="updateParams[index].value1"
                  />
                </div>
                <div style="width: 20px">
                  <div style="line-height: 32px; margin-left: 5px">
                    <a-icon v-if="index > 0" type="minus-circle" @click="removeUpdateParams(index)" />
                    <a-icon v-if="index == 0" type="plus-circle" @click="addUpdateParams" />
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div
            style="
              margin-left: 30px;
              justify-content: flex-end;
              display: flex;
              align-items: center;
              height: 60px;
              padding-right: 50px;
            "
          >
            <a-button @click="handlerInsert">新增</a-button>
            <a-button @click="handlerUpdate">更新</a-button>
            <a-button @click="handlerDelete">删除</a-button>
          </div>
          <div :style="{ borderBottom: '1px solid #E9E9E9' }">
            <a-checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange">
              全选
            </a-checkbox>
            <a-button @click="addUpdateItem"><a-icon type="plus-circle" />新增</a-button>
            <a-button @click="removeUpdateItem"><a-icon type="minus-circle" />移除</a-button>
            <a-button @click="addToUpdateParams"><a-icon type="plus-circle" />设为更新条件</a-button>
          </div>
          <a-checkbox-group v-model="checkedList" @change="onChange">
            <div style="display: flex; flex-wrap: wrap; justify-content: flex-start">
              <template v-for="(item, index) in updateItems">
                <div :key="'item' + index" style="width: 450px;display: flex;padding:5px;10px;margin-right:30px">
                  <a-checkbox :value="updateItems[index].key"></a-checkbox>
                  <div style="width: 200px; text-align: right; line-height: 32px; padding-right: 5px">
                    <a-input v-model="updateItems[index].key" />
                  </div>
                  <a-input v-model="updateItems[index].value" />
                  <div style="line-height: 32px">
                    <a-icon type="minus-circle" @click="removeUpdateAttr(updateItems.dataIndex)" />
                  </div>
                </div>
              </template>
            </div>
          </a-checkbox-group>
        </a-collapse-panel>
      </a-collapse>
    </a-form-model>
  </div>
</template>
<script>
import { postAction } from '@/api/manage'
import cloneDeep from 'lodash/cloneDeep'
import { UtilsMixin } from '@/mixins/UtilsMixin'
export default {
  mixins: [UtilsMixin],
  name: 'CommonQuery',
  components: {},
  data() {
    return {
      activeKey: ['1', '2'],
      labelCol: { span: 2 },
      wrapperCol: { span: 21 },
      urls: {
        codes: '/manage/codeInfo/queryByTypes',
        commonQuery: '/common/commonQuery',
        commonUpdate: '/common/commonUpdate',
        commonDelete: '/common/commonDelete',
      },
      codes: ['CommonHandlerOptions'],
      projectType: [],
      handlerType: [],
      filterOptions: [],
      codeMaps: {},
      pagination: {
        offset: 0,
        total: 0,
        current: 1,
        pageSize: 10,
        pageSizeOptions: ['10', '20', '30', '40', '50'],
        showTotal: (total, range) => {
          return range[0] + '-' + range[1] + ' 共' + total + '条'
        },
      },
      operator: [
        { code: '=', name: '等于' },
        { code: '>', name: '大于' },
        { code: '>=', name: '大于等于' },
        { code: '<', name: '小于' },
        { code: '<=', name: '小于等于' },
        { code: 'in', name: '包含' },
        { code: 'like', name: 'Like' },
        { code: 'between', name: 'Between' },
      ],
      columns: [],
      records: [],
      record: {},
      queryBean: '',
      queryTableName: '',
      updateBean: '',
      updateTableName: '',
      queryParams: [{}],
      updateParams: [{}],
      maxSize: 1,
      checkedList: [],
      indeterminate: true,
      checkAll: false,
      hotOptions: [{ code: '' }],
      updateName: '',
      queryName: '',
      searchTimeOut: null,
      searchKey: null,
      commonQueryOptions: this.$store.getters.commonQueryOptions,
      showCommonQueryOptions: this.$store.getters.commonQueryOptions,
      updateParamsTemp: [],
      updateItems: [],
    }
  },
  computed: {
    recordColumns() {
      if (this.record) {
        let temp = []
        for (var key in this.record) {
          temp.push(this.makeColumn(key))
        }
        return temp
      }
      return []
    },
    // ...mapState({
    //
    // }),
    // commonQueryOptions() {
    //   let commonQueryOptions = this.$store.getters.commonQueryOptions
    //   if (!commonQueryOptions) {
    //     return []
    //   } else {
    //     return commonQueryOptions
    //   }
    // },
  },
  mounted() {},
  methods: {
    handleSearch(value) {
      if (this.commonQueryOptions.indexOf(value) < 0) {
        this.showCommonQueryOptions = [value, ...this.commonQueryOptions]
      }
    },
    calcQueryTableName() {
      if (this.queryBean) {
        if (this.queryBean && this.queryBean.indexOf('ServiceImpl') > -1) {
          this.queryTableName = this.camelToUnderline(this.queryBean.replace('ServiceImpl', ''))
        } else {
          this.queryTableName = this.camelToUnderline(this.queryBean)
        }
      }
    },
    calcUpdateTableName() {
      if (this.updateBean) {
        if (this.updateBean && this.updateBean.indexOf('ServiceImpl') > -1) {
          this.updateTableName = this.camelToUnderline(this.updateBean.replace('ServiceImpl', ''))
        } else {
          this.updateTableName = this.camelToUnderline(this.updateBean)
        }
      }
    },

    changeQueryOptions(bean) {
      this.updateBean = bean
      this.calcQueryTableName()
      this.calcUpdateTableName()
      this.$set(this.queryParams[0], 'key', '')
      this.$set(this.queryParams[0], 'operator', '等于')
    },
    changeUpdateOptions(bean) {
      this.updateBean = bean
      this.calcUpdateTableName()
      this.$set(this.updateParams[0], 'key', '')
      this.$set(this.updateParams[0], 'operator', '等于')
    },
    customRow(record) {
      return {
        on: {
          dblclick: (event) => {
            this.record = cloneDeep(record)
          },
        },
      }
    },
    pageChange(current, pageSize) {
      this.$set(this.pagination, 'pageSize', pageSize)
      this.$set(this.pagination, 'current', current)
      this.fetchList()
    },
    onShowSizeChange(current, pageSize) {
      this.$set(this.pagination, 'pageSize', pageSize)
      this.$set(this.pagination, 'current', 1)
      this.fetchList()
    },
    handlerSearch() {
      this.$set(this.pagination, 'current', 1)
      this.$set(this, 'updateParams', cloneDeep(this.queryParams))
      this.fetchList()
    },
    fetchList() {
      if (!this.queryBean) {
        return this.$message.warning('请输入查询Bean')
      }
      if (this.queryParams) {
        let i = 1
        for (let p of this.queryParams) {
          if (!p.key || !p.operator || !p.key.trim() || !p.operator.trim()) {
            return this.$message.warning('第【' + i + '】条件设置不正确，请确认')
          }
        }
      } else {
        return this.$message.warning('请至少输入一个条件')
      }
      if (!this.queryTableName) {
        return this.$message.warning('请输入查询表名')
      }
      postAction(
        this.urls.commonQuery +
          '?bean=' +
          this.queryBean +
          '&current=' +
          this.pagination.current +
          '&size=' +
          this.pagination.pageSize +
          '&tableName=' +
          this.queryTableName,
        this.queryParams
      ).then((res) => {
        if (res.success) {
          this.saveToLocalStorage(this.queryBean)
          this.records = res.result.records
          this.$set(this.pagination, 'total', res.result.total)
          if (this.records && this.records.length > 0) {
            let columnList = []
            for (var key in this.records[0]) {
              columnList.push(this.makeColumn(key))
            }
            this.records.forEach((r) => {
              r.randomStr = this.getRandomStr(10)
            })
            this.columns = columnList
          }
          this.$message.success('查询成功')
        } else {
          this.$message.error(res.message)
        }
      })
    },
    handlerInsert() {
      if (!this.updateItems && this.updateItems.length <= 0) {
        return this.$message.warning('请至少选择一个需要更新则项目')
      }
      let columns = []
      for (let key in this.record) {
        if (['__row_number__', 'randomStr'].indexOf(key) < 0) {
          columns.push(key.trim())
        }
      }
      for (let item of this.updateItems) {
        if (columns.indexOf(item.key.trim()) >= 0) {
          if (!item.key || item.key.trim() == '') {
            return this.$message.warning('请输入字段名')
          }
        } else {
          return this.$message.warning('表中不存在字段【' + item.key + '】，请确认')
        }
      }
      let params = {}
      params['setMap'] = this.updateItems
      if (!this.updateTableName) {
        return this.$message.warning('请输入更新表名')
      }
      postAction(
        this.urls.commonInsert + '?bean=' + this.updateBean + '&tableName=' + this.updateTableName,
        params
      ).then((res) => {
        this.saveToLocalStorage(this.updateBean)
        if (res.success) {
          this.$message.success('执行成功')
        } else {
          this.$message.warning('执行失败:' + res.message)
        }
      })
    },
    handlerUpdate() {
      if (!this.updateBean) {
        return this.$message.warning('请输入查询Bean')
      }
      if (this.updateParams) {
        let i = 1
        for (let p of this.updateParams) {
          if (!p.key && !p.value && !p.operator && !p.key.trim() && !p.value.trim() && !p.operator.trim()) {
            return this.$message.warning('第【' + i + '】条件设置不正确，请确认')
          }
        }
      } else {
        return this.$message.warning('请至少输入一个条件')
      }

      let params = {}
      params['condition'] = this.updateParams
      if (!this.updateItems && this.updateItems.length <= 0) {
        return this.$message.warning('请至少选择一个需要更新则项目')
      }
      let columns = []
      for (let key in this.record) {
        if (['__row_number__', 'randomStr'].indexOf(key) < 0) {
          columns.push(key.trim())
        }
      }
      for (let item of this.updateParams) {
        if (columns.indexOf(item.key.trim()) >= 0) {
          if (!item.key || item.key.trim() == '') {
            return this.$message.warning('请输入字段名')
          }
          if (!item.operator || item.operator.trim() == '') {
            return this.$message.warning('请选择操作类型')
          }
          if (!item.value || item.value.trim() == '') {
            return this.$message.warning('请输入字段值')
          }
          if (item.operator == 'Between') {
            if (!item.value1 || item.value1.trim() == '') {
              return this.$message.warning('请输入字段值')
            }
          }
        } else {
          return this.$message.warning('表中不存在字段【' + item.key + '】，请确认')
        }
      }
      let updateItems = []
      for (let item of this.updateItems) {
        if (columns.indexOf(item.key.trim()) >= 0) {
          if (!item.key || item.key.trim() == '') {
            return this.$message.warning('请输入字段名')
          }
          // if (!item.value || item.value.trim() == '') {
          //   return this.$message.warning('请输入字段值')
          // }
        } else {
          return this.$message.warning('表中不存在字段【' + item.key + '】，请确认')
        }
        if (['__row_number__', 'randomStr', 'id', 'nid', 'pid'].indexOf(item.key.trim()) < 0) {
          updateItems.push(item)
        }
      }
      params['setMap'] = updateItems
      if (!this.updateTableName) {
        return this.$message.warning('请输入更新表名')
      }
      postAction(
        this.urls.commonUpdate +
          '?bean=' +
          this.updateBean +
          '&maxSize=' +
          this.maxSize +
          '&tableName=' +
          this.updateTableName,
        params
      ).then((res) => {
        if (res.success) {
          this.saveToLocalStorage(this.updateBean)
          this.$message.success('执行成功')
        } else {
          this.$message.warning('执行失败:' + res.message)
        }
      })
    },
    handlerDelete() {
      if (!this.updateBean) {
        return this.$message.warning('请输入查询Bean')
      }
      if (this.updateParams) {
        let i = 1
        for (let p of this.updateParams) {
          if (!p.key && !p.value && !p.operator && !p.key.trim() && !p.value.trim() && !p.operator.trim()) {
            return this.$message.warning('第【' + i + '】条件设置不正确，请确认')
          }
        }
      } else {
        return this.$message.warning('请至少输入一个条件')
      }

      let params = {}
      params['condition'] = this.updateParams
      if (!this.updateTableName) {
        return this.$message.warning('请输入更新表名')
      }
      postAction(
        this.urls.commonDelete +
          '?bean=' +
          this.updateBean +
          '&maxSize=' +
          this.maxSize +
          '&tableName=' +
          this.updateTableName,
        params
      ).then((res) => {
        if (res.success) {
          this.saveToLocalStorage(this.updateBean)
          this.$message.success('执行成功')
        } else {
          this.$message.warning('执行失败:' + res.message)
        }
      })
    },
    getRandomStr(len) {
      len = len || 32
      var $chars =
        'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
      var maxPos = $chars.length
      var pwd = ''
      for (let i = 0; i < len; i++) {
        pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
      }
      return pwd
    },
    makeColumn(key) {
      let column = {
        title: key,
        dataIndex: key,
        width: '200px',
        align: 'center',
        customCell: () => {
          return {
            style: {
              width: '200px',
              overflow: 'hidden',
              whiteSpace: 'nowrap',
              textOverflow: 'ellipsis',
              cursor: 'pointer',
            },
          }
        },
        customRender: (text, record) => (
          <a-tooltip placement="topLeft" title={text}>
            {text}
          </a-tooltip>
        ),
      }
      return column
    },
    addQueryParams() {
      this.queryParams.push({})
    },
    addUpdateParams() {
      this.updateParams.push({})
    },
    addUpdateItem() {
      let items = this.updateItems
      if (!items || items.length <= 0) {
        items = []
      }
      items.push({})
      this.updateItems = items
    },
    removeUpdateItem() {
      if (!this.checkedList || this.checkedList.length <= 0) {
        return this.$message.warning('请至少选择一个项目进行操作')
      } else {
        let updateParamsKey = []
        for (var param of this.updateParams) {
          updateParamsKey.push(param.key)
        }
        let newList = []
        for (let item of this.updateItems) {
          if (this.checkedList.indexOf(item.key) < 0) {
            newList.push({ key: item.key, operator: '等于', value: item.value })
          }
        }
        this.updateItems = newList
        this.checkedList = []
      }
    },
    addToUpdateParams() {
      if (!this.checkedList || this.checkedList.length <= 0) {
        return this.$message.warning('请至少选择一个项目进行操作')
      } else {
        let newList = []
        for (let item of this.updateItems) {
          if (this.checkedList.indexOf(item.key) > -1) {
            newList.push(item)
          }
        }
        this.updateParams = [...this.updateParams, ...newList]
      }
    },
    initUpdateItems() {
      if (this.record) {
        let temp = []
        for (var key in this.record) {
          temp.push({ key: key, value: this.record[key] })
        }
        this.updateItems = temp
      } else {
        this.updateItems = []
      }
    },
    removeQueryParams(index) {
      let queryParams = []
      let i = 0
      for (let p of this.queryParams) {
        if (i != index) {
          queryParams.push(p)
        }

        i++
      }
      this.queryParams = queryParams
    },
    removeUpdateParams(index) {
      let updateParams = []
      let i = 0
      for (let p of this.updateParams) {
        if (i != index) {
          updateParams.push(p)
        }

        i++
      }
      this.updateParams = updateParams
    },
    removeUpdateAttr(attr) {
      let newObj = {}
      for (let key in this.record) {
        if (key != attr) {
          newObj[key] = this.record[key]
        }
      }
      this.record = Object.assign({}, newObj)
    },
    onChange(checkedList) {
      this.indeterminate = !!checkedList.length && checkedList.length < this.recordColumns.length
      this.checkAll = checkedList.length === this.updateItems.length
    },
    onCheckAllChange(e) {
      let columnList = []
      for (let item of this.updateItems) {
        columnList.push(item.key)
      }
      Object.assign(this, {
        checkedList: e.target.checked ? columnList : [],
        indeterminate: false,
        checkAll: e.target.checked,
      })
    },
    saveToLocalStorage(bean) {
      let commonQueryOptions = this.$store.getters.commonQueryOptions
      if (!commonQueryOptions) {
        commonQueryOptions = []
      }

      if (commonQueryOptions.indexOf(bean) < 0) {
        commonQueryOptions.push(bean.trim())
        this.$store.commit('SET_COMMON_QUERY_OPTIONS', commonQueryOptions)
      }
    },
    deleteItem(bean) {
      let commonQueryOptions = this.$store.getters.commonQueryOptions
      if (!commonQueryOptions) {
        commonQueryOptions = []
      }
      if (commonQueryOptions.indexOf(bean) > -1) {
        commonQueryOptions.splice(commonQueryOptions.indexOf(bean), 1)
      }
      this.$store.commit('SET_COMMON_QUERY_OPTIONS', commonQueryOptions)
    },
  },
  watch: {
    '$store.getters.commonQueryOptions': function () {
      this.commonQueryOptions = this.$store.getters.commonQueryOptions
    },
    record(value) {
      if (this.record) {
        let temp = []
        let updateParamsKey = []
        for (var param of this.updateParamsTemp) {
          updateParamsKey.push(param.key)
        }
        let recordKey = []
        for (var key in this.record) {
          if (['__row_number__', 'randomStr'].indexOf(key) < 0) {
            temp.push({ key: key, value: this.record[key] })
          }
          recordKey.push(key)
        }
        if (updateParamsKey.indexOf('id') < 0 && recordKey.indexOf('id') > -1) {
          this.updateParams.push({ key: 'id', operator: '等于', value: this.record.id })
        }
        this.updateParamsTemp = this.updateParams
        this.updateItems = temp
      } else {
        this.updateParamsTemp = []
        this.updateItems = []
      }
    },
  },
}
</script>
<style>
</style>